/*********************************************************************************/
/*                                                                               */
/*      SPI Driver                                                               */
/*                                                                               */
/*      Last updated by:   CBS                                                   */
/*      Last update date:  13/01/15                                              */
/*      Revision:          0                                                     */
/*      Copyright:         DENSO                                                 */
/*                                                                               */
/*********************************************************************************/

#ifndef SPI_CFG_H_
#define SPI_CFG_H_
/*********************************************************************************/
/*  include files                                                                */
/*********************************************************************************/
#include "Mcu.h"
#include "Dma.h"
#include "Spi.h"


/*********************************************************************************/
/*  defines / data types / structs / unions / macros                             */
/*********************************************************************************/
#define DSPI_CTRL_A 0
#define DSPI_CTRL_B 1
#define DSPI_CTRL_C 2
#define DSPI_CTRL_D 3

#define SPI_EB_MAX_LENGTH           64

/*********************************************************************************/
/*  LEVEL 0 - Only Internal buffers                                              */
/*  LEVEL 1 - Only external buffers                                              */
/*  LEVEL 2 - Both internal/external buffers                                     */
/*********************************************************************************/
#define SPI_CHANNEL_BUFFERS_ALLOWED  0         /* currently only support level 0 */

/*********************************************************************************/
/*  LEVEL 0 - Simple sync                                                        */
/*  LEVEL 1 - Basic  async                                                       */
/*  LEVEL 2 - Enhanced mode                                                      */
/*********************************************************************************/
#define SPI_LEVEL_DELIVERED          0         /* currently only support level 0 */

#define SPI_VERSION_INFO_API         STD_ON

#define INT_MAX 65535

/* Uncertain */
#define E2_WREN  0x6   /* Write Enable */
#define E2_REDI  0x4   /* Write Disable */
#define E2_RDSR  0x5   /* Read Status Register */
#define E2_WRSR  0x1   /* Write Status Register */
#define E2_READ  0x3   /* Read from Memory Array */
#define E2_WRITE 0x2   /* Write to Memery Array */

#define FLASH_READ_25         0x03
#define FLASH_READ_50         0x0B
#define FLASH_RDSR            0x05
#define FLASH_JEDEC_ID        0x9f
#define FLASH_RDID            0x90
#define FLASH_BYTE_WRITE      0x02
#define FLASH_AI_WORD_WRITE   0xad
#define FLASH_WREN            0x06
#define FLASH_WRDI            0x04
#define FLASH_WRSR            0x01
#define FLASH_ERASE_4K        0x20

typedef U2 Spi_NumberOfDataType;

typedef enum{
    SPI_EB,     /* External Buffer */
    SPI_IB      /* Internal Buffer */
} Spi_BufferType;

typedef enum{
    SPI_EXT_DEVICE_A_E2,
    SPI_EXT_DEVICE_A_FLASH,
    SPI_EXT_DEVICE_B_E2 
} Spi_ExternalDeviceTypeType;

typedef enum{
    SPI_CH_E2_CMD = 0,
    SPI_CH_E2_ADDR,
    SPI_CH_E2_WREN,
    SPI_CH_E2_DATA,
    
    SPI_CH_EEP_CMD,
    SPI_CH_EEP_ADDR,
    SPI_CH_EEP_WREN,
    SPI_CH_EEP_DATA,
    
    SPI_CH_FLASH_CMD,
    SPI_CH_FLASH_ADDR,
    SPI_CH_FLASH_DATA,
    SPI_CH_FLASH_WREN,
    SPI_CH_FLASH_WRDI,
    SPI_CH_FLASH_WRSR,
    
    SPI_CH_TEST_0,
    SPI_CH_TEST_1,
    SPI_CH_TEST_2,
    SPI_CH_TEST_3,
    
    SPI_MAX_CHANNEL = 4
}Spi_ChannelType;

typedef enum
{
    SPI_JOB_E2_CMD = (U4)0,
    SPI_JOB_E2_CMD2,
    SPI_JOB_E2_DATA,
    SPI_JOB_E2_WREN,
    
    SPI_JOB_EEP_CMD,
    SPI_JOB_EEP_CMD2,
    SPI_JOB_EEP_DATA,
    SPI_JOB_EEP_WREN,
    
    SPI_JOB_FLASH_CMD,
    SPI_JOB_FLASH_CMD2,
    SPI_JOB_FLASH_CMD_DATA,
    SPI_JOB_FLASH_READ,
    SPI_JOB_FLASH_WREN,
    SPI_JOB_FLASH_WRDI,
    SPI_JOB_FLASH_DATA,
    SPI_JOB_FLASH_WRSR,
    SPI_JOB_FLASH_ADDR,
    
    SPI_JOB_TEST_0,
    SPI_JOB_TEST_1,
    SPI_JOB_TEST_2,
    SPI_JOB_TEST_3,

    SPI_MAX_JOB = 6
} Spi_JobType;

#define SPI_MAX_CHANNELS  8

typedef enum
{
    SPI_SEQ_E2_CMD = (U4)0,
    SPI_SEQ_E2_CMD2,
    SPI_SEQ_E2_READ,
    SPI_SEQ_E2_WRITE,
    
    SPI_SEQ_EEP_CMD,
    SPI_SEQ_EEP_CMD2,
    SPI_SEQ_EEP_READ,
    SPI_SEQ_EEP_WRITE,
    
    SPI_SEQ_FLASH_CMD,
    SPI_SEQ_FLASH_CMD2,
    SPI_SEQ_FLASH_CMD_DATA,
    SPI_SEQ_FLASH_READ,
    SPI_SEQ_FLASH_WRITE,
    SPI_SEQ_FLASH_WRSR,
    SPI_SEQ_FLASH_ERASE,
    
    SPI_SEQ_TEST,
    
    
    SPI_MAX_SEQUENCE = (U4)32
} Spi_SequenceType;

typedef enum{
    SPI_EDGE_LEADING,
    SPI_EDGE_TRAILING
} Spi_EdgeType;

typedef struct{
    Spi_ChannelType SpiChannelId;
    
    Spi_BufferType SpiChannelType;
    
    U4 SpiDataWidth;
    U4 SpiDefaultData;
    
    Spi_NumberOfDataType SpiEbMaxLength;
    
    Spi_NumberOfDataType SpiIbNBuffers;
    
    Bool SpiDmaNoIncreaseSrc;
} Spi_ChannelConfigType;

typedef struct{
    Spi_JobType SpiJobId;
    /* Priority */
    U4 SpiHwUnit;
    
    U4 ChannelAssignment[SPI_MAX_CHANNELS];
    
    Spi_ExternalDeviceTypeType DeviceAssignment;
} Spi_JobConfigType;

typedef struct{
    U4 SpiBaudrate;
    U4 SpiCsIdentifier;
    U1 SpiCsPolarity;
    Spi_EdgeType SpiDataShiftEdge;
    U1 SpiEnableCs;
    U1 SpiShiftClockIdleLevel;
    U4 SpiTimeClk2Cs;
    U4 SpiTimeCs2Clk;
} Spi_ExternalDeviceType;

typedef struct{
    Spi_SequenceType SpiSequenceId;
    U4 JobAssignment[SPI_MAX_JOB];
} Spi_SequenceConfigType;

typedef struct
{
#if 0
  /* Interrupt priority level for this SPI channel. */
  U1 IsrPriority;
#endif
  /* This channel is to be activated for use. */
  U1 Activated;

  /* Receive DMA channel. */
  Dma_ChannelType RxDmaChannel;

  /* Transmit DMA channel. */
  Dma_ChannelType TxDmaChannel;

  /* Peripheral clock source. */
  /* McuE_PeriperalClock_t PeripheralClock; */
} Spi_HwConfigType;

typedef struct
{
  U1 SpiMaxChannel;

  U1 SpiMaxJob;

  U1 SpiMaxSequence;

  /* All data needed to configure one SPI-channel */
  const Spi_ChannelConfigType* SpiChannelConfig;

  /* The communication settings of an external device */
  const Spi_ExternalDeviceType* SpiExternalDevice;

  /* All data needed to configure one SPI-Job */
  const Spi_JobConfigType *SpiJobConfig;

  /* All data needed to configure one SPI-sequence */
  const Spi_SequenceConfigType *SpiSequenceConfig;

  const Spi_HwConfigType *SpiHwConfig;
} Spi_DriverType;

typedef Spi_DriverType Spi_ConfigType;

typedef U4 Spi_DataType;

typedef U4 Spi_HWUnitType;

extern const Spi_ConfigType SpiConfigData;

U4 Spi_GetJobCnt(void);
U4 Spi_GetChannelCnt(void);
U4 Spi_GetExternalDeviceCnt(void);

/*********************************************************************************/
/*  API Functions                                                                */
/*********************************************************************************/
#endif